package org.example.service;

import lombok.extern.slf4j.Slf4j;
import org.example.calculator.VintageCalculator;
import org.example.entity.CustomerInfo;
import org.example.entity.CustomerOrder;
import org.example.entity.CustomerRepayPlan;
import org.example.generator.DataGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 数据服务类
 */
@Service
@Slf4j
public class DataService {
    
    @Autowired
    private CustomerInfoService customerInfoService;
    
    @Autowired
    private CustomerOrderService customerOrderService;
    
    @Autowired
    private CustomerRepayPlanService customerRepayPlanService;
    
    private static final String FUND_SOURCE_BEFORE_2023_07 = "浩瀚";
    
    // 资金方占比
    private static final Map<String, Double> FUND_SOURCE_RATIO = new HashMap<>();
    static {
        FUND_SOURCE_RATIO.put("盈峰小贷", 0.30);
        FUND_SOURCE_RATIO.put("浩瀚小贷", 0.30);
        FUND_SOURCE_RATIO.put("新网银行", 0.20);
        FUND_SOURCE_RATIO.put("江山小贷", 0.20);
    }
    
    /**
     * 生成并插入数据
     */
    public void generateAndInsertData() {
        try {
            // 清空现有数据
            clearExistingData();

            
//            // 生成数据
            List<CustomerInfo> customers = new ArrayList<>();
            List<CustomerOrder> orders = new ArrayList<>();
            List<CustomerRepayPlan> repayPlans = new ArrayList<>();
            DataGenerator.DataGenerationResult result =DataGenerator.generateCompleteDataSet();
            customers = result.getCustomers();
            orders = result.getOrders();
            repayPlans = result.getRepayPlans();
//
//            // 目标数据量
////            BigDecimal targetTotalLoan = new BigDecimal("5000000000"); // 50亿元
//            BigDecimal targetTotalLoan = new BigDecimal("500000"); // 50万元
//
//            BigDecimal averageLoanAmount = new BigDecimal("5000");
//
//            // 估算需要生成的订单数量
//            int estimatedOrderCount = targetTotalLoan.divide(averageLoanAmount, 0, RoundingMode.UP).intValue();
//
//            System.out.println("开始生成数据，预计生成订单数量: " + estimatedOrderCount);
//
//            // 从2023年7月开始生成数据，到2025年8月结束
//            LocalDate startDate = LocalDate.of(2023, 7, 1);
//            LocalDate endDate = LocalDate.of(2025, 8, 31);
//
//            BigDecimal totalGeneratedLoan = BigDecimal.ZERO;
//            int generatedOrderCount = 0;
//
//            // 按月生成数据
//            LocalDate monthDate = startDate;
//            while (!monthDate.isAfter(endDate)) {
//                // 计算当月需要生成的订单数量（递增趋势）
//                int monthOrderCount = calculateMonthlyOrderCount(monthDate, startDate, estimatedOrderCount);
//
//                System.out.println("生成 " + monthDate.format(DateTimeFormatter.ofPattern("yyyy-MM")) + " 月数据，订单数量: " + monthOrderCount);
//
//                for (int i = 0; i < monthOrderCount; i++) {
//                    if (totalGeneratedLoan.compareTo(targetTotalLoan) >= 0) {
//                        break;
//                    }
//
//                    // 生成用户信息（传递订单日期）
//                    CustomerInfo customer = DataGenerator.generateCustomerInfo(monthDate);
//                    customers.add(customer);
//
//                    // 确定资金方
//                    String fundSource = determineFundSource(monthDate);
//
//                    // 生成订单
//                    CustomerOrder order = DataGenerator.generateCustomerOrder(customer, monthDate, fundSource);
//                    orders.add(order);
//
//                    // 生成还款计划
//                    List<CustomerRepayPlan> plans = DataGenerator.generateRepayPlan(order);
//                    repayPlans.addAll(plans);
//
//                    totalGeneratedLoan = totalGeneratedLoan.add(order.getLoanAmount());
//                    generatedOrderCount++;
//                }
//
//                monthDate = monthDate.plusMonths(1);
//            }
//
//            System.out.println("数据生成完成，实际生成订单数量: " + generatedOrderCount);
//            System.out.println("实际生成放款总额: " + totalGeneratedLoan + " 元");


            log.info("生成数据统计:");
            log.info("客户数量: {}", customers.size());
            log.info("订单数量: {}", orders.size());
            log.info("还款计划数量: {}", repayPlans.size());
            
            // 插入数据到数据库
            insertCustomers(customers);
            insertOrders(orders);
            insertRepayPlans(repayPlans);
            
            // 计算并显示Vintage和迁徙率
            calculateAndDisplayReports(orders, repayPlans);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 计算每月订单数量（递增趋势）
     */
    private int calculateMonthlyOrderCount(LocalDate monthDate, LocalDate startDate, int totalOrders) {
        long monthsFromStart = java.time.temporal.ChronoUnit.MONTHS.between(startDate, monthDate);
        
        // 递增趋势：每月增长2%（降低增长率以确保能生成到2025年8月）
        double growthRate = 1.02;
        double monthlyRatio = Math.pow(growthRate, monthsFromStart);
        
        // 基础每月订单数（26个月：2023年7月到2025年8月）
        // 调整基础订单数，确保50亿元能分布到26个月
        int baseMonthlyOrders = totalOrders / 30; // 减少基础订单数
        
        // 确保每月至少有50个订单
        int monthlyOrders = (int) (baseMonthlyOrders * monthlyRatio);
        return Math.max(monthlyOrders, 50);
    }
    
    /**
     * 确定资金方
     */
    private String determineFundSource(LocalDate loanDate) {
        LocalDate splitDate = LocalDate.of(2023, 7, 1);
        
        if (loanDate.isBefore(splitDate)) {
            return FUND_SOURCE_BEFORE_2023_07;
        } else {
            // 根据占比随机选择资金方
            double random = ThreadLocalRandom.current().nextDouble();
            double cumulative = 0.0;
            
            for (Map.Entry<String, Double> entry : FUND_SOURCE_RATIO.entrySet()) {
                cumulative += entry.getValue();
                if (random <= cumulative) {
                    return entry.getKey();
                }
            }
            
            return "浩瀚小贷"; // 默认
        }
    }
    
    /**
     * 清空现有数据
     */
    public void clearExistingData() {
        customerRepayPlanService.remove(null);
        customerOrderService.remove(null);
        customerInfoService.remove(null);
    }
    
    /**
     * 插入用户信息
     */
    private void insertCustomers(List<CustomerInfo> customers) {
        customerInfoService.saveBatch(customers);
        System.out.println("用户信息插入完成，数量: " + customers.size());
    }
    
    /**
     * 插入客户订单
     */
    private void insertOrders(List<CustomerOrder> orders) {
        customerOrderService.saveBatch(orders);
        System.out.println("客户订单插入完成，数量: " + orders.size());
    }
    
    /**
     * 插入客户还款计划
     */
    private void insertRepayPlans(List<CustomerRepayPlan> repayPlans) {
        customerRepayPlanService.saveBatch(repayPlans);
        System.out.println("客户还款计划插入完成，数量: " + repayPlans.size());
    }
    
    /**
     * 计算并显示报告
     */
    private void calculateAndDisplayReports(List<CustomerOrder> orders, List<CustomerRepayPlan> repayPlans) {
        System.out.println("\n=== 数据统计报告 ===");
        
        // 计算迁徙率
        Map<String, BigDecimal> migrationRates = VintageCalculator.calculateMigrationRate(repayPlans);
        VintageCalculator.generateMigrationReport(migrationRates);
        
        // 计算Vintage逾期率
        Map<String, Map<String, BigDecimal>> vintageResults = VintageCalculator.calculateVintageRates(orders, repayPlans);
        VintageCalculator.generateVintageReport(vintageResults);
        
        // 计算在途余额
        BigDecimal outstandingAmount = orders.stream()
                .filter(order -> "未结清".equals(order.getStatus()))
                .map(CustomerOrder::getRemainPayAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        System.out.println("\n=== 业务指标 ===");
        System.out.println("在途贷款余额: " + outstandingAmount + " 元");
        
        BigDecimal totalLoanAmount = orders.stream()
                .map(CustomerOrder::getLoanAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println("总放款金额: " + totalLoanAmount + " 元");
        
        // 计算提前还款比例
        long earlyRepayCount = orders.stream()
                .filter(order -> "已结清".equals(order.getStatus()) && order.getSettleDate() != null)
                .count();
        double earlyRepayRatio = (double) earlyRepayCount / orders.size() * 100;
        System.out.println("提前还款比例: " + String.format("%.2f", earlyRepayRatio) + "%");
    }
}
